home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / mpeg_play-2.1 / readfile.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  26KB  |  999 lines

  1. /*
  2.  * readfile.c --
  3.  *
  4.  *       Procedures concerned with reading data and parsing 
  5.  *       start codes from MPEG files.
  6.  *
  7.  */
  8.  
  9. /*
  10.  * Copyright (c) 1995 The Regents of the University of California.
  11.  * All rights reserved.
  12.  * 
  13.  * Permission to use, copy, modify, and distribute this software and its
  14.  * documentation for any purpose, without fee, and without written agreement is
  15.  * hereby granted, provided that the above copyright notice and the following
  16.  * two paragraphs appear in all copies of this software.
  17.  * 
  18.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  19.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  20.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  21.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22.  * 
  23.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  24.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  25.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  26.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  27.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  28.  */
  29.  
  30. #include "video.h"
  31. #include "proto.h"
  32. #include <sys/types.h>
  33. #include <signal.h>
  34. #ifndef MIPS
  35. #include <netinet/in.h>
  36. #else
  37. #include <bsd/netinet/in.h>
  38. #endif
  39.  
  40. #include "util.h"
  41. #include "dither.h"
  42.  
  43. /* 
  44.   Are we a system layer parser or pure video?
  45.   (-1 is uninit, 0 is video, 1 is sys_layer)
  46. */
  47. int sys_layer = -1;
  48. int audBytes,vidBytes,sysBytes;
  49.  
  50. /* End of File flag. */
  51. extern int EOF_flag;
  52.  
  53. /* Global file pointer to incoming data. */
  54. extern FILE *input;
  55.  
  56. /* Values to handle stream seeking */
  57. extern int seekValue;
  58. extern unsigned int *bitBuffer;
  59. extern int bufLength;
  60.  
  61. /* Options to control logging */
  62. extern FILE *syslogOutput;
  63. extern int opts;
  64.  
  65. /* Silly Constants.... */
  66. #define PACK_START_CODE             ((unsigned int)0x000001ba)
  67. #define SYSTEM_HEADER_START_CODE    ((unsigned int)0x000001bb)
  68. #define PACKET_START_CODE_MASK      ((unsigned int)0xffffff00)
  69. #define PACKET_START_CODE_PREFIX    ((unsigned int)0x00000100)
  70. #define ISO_11172_END_CODE          ((unsigned int)0x000001b9)
  71.   
  72. #define PACK_HEADER_SIZE 8
  73.   
  74. #define STD_AUDIO_STREAM_ID ((unsigned char) 0xb8)
  75. #define STD_VIDEO_STREAM_ID ((unsigned char) 0xb9)
  76. #define MIN_STREAM_ID_ID    ((unsigned char) 0xbc)
  77. #define RESERVED_STREAM_ID  ((unsigned char) 0xbc)
  78. #define PRIVATE_STREAM_1_ID ((unsigned char) 0xbd)
  79. #define PADDING_STREAM_ID   ((unsigned char) 0xbe)
  80. #define PRIVATE_STREAM_2_ID ((unsigned char) 0xbf)
  81.   
  82. #define STD_SYSTEM_CLOCK_FREQ (unsigned long)90000
  83. #define MUX_RATE_SCALE_FACTOR 50
  84. #define MAX_STREAMS 8
  85. #define NOT_PACKET_ID       ((unsigned char) 0xff)
  86. #define KILL_BUFFER         ((unsigned char) 0xfe)
  87.   
  88.  
  89. /*
  90.  *--------------------------------------------------------------
  91.  *
  92.  * get_more_data --
  93.  *
  94.  *    Called by get_more_data to read in more data from
  95.  *      video MPG files (non-system-layer)
  96.  *
  97.  * Results:
  98.  *    Input buffer updated, buffer length updated.
  99.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  100.  *
  101.  * Side effects:
  102.  *      None.
  103.  *
  104.  *--------------------------------------------------------------
  105.  */
  106. int 
  107. get_more_data(bs_ptr, max_length, length_ptr, buf_ptr)
  108.       unsigned int **bs_ptr;
  109.       int *max_length, *length_ptr;
  110.       unsigned int **buf_ptr;
  111. {
  112.   static BOOLEAN swap;
  113.   int ioBytes, data, result;
  114.   unsigned int *mark;
  115.   
  116.   if (sys_layer == 0) {
  117.     return pure_get_more_data(*bs_ptr, *max_length, length_ptr, buf_ptr, swap);
  118.   }
  119.  
  120.   if (sys_layer == -1) {
  121.     /* Time to init ourselves */
  122.     swap = (htonl(1) != 1);
  123.     mark = *bs_ptr;
  124.     ioBytes = fread(&data, 1, 4, input);
  125.  
  126.     if (ioBytes != 4) {
  127.       return 0;
  128.     }
  129.  
  130.     data = ntohl(data);
  131.     if ( (data == PACK_START_CODE) || (data == SYSTEM_HEADER_START_CODE) ) {
  132.       /* Yow, a System Layer Stream.  Much harder to parse.  Call in the
  133.          specialist.... */
  134.       fprintf(stderr,"This is an MPEG System Layer Stream.  ");
  135.       fprintf(stderr,"Audio is not played.\n");
  136.       sys_layer = 1;
  137.       result = read_sys(bs_ptr, max_length, length_ptr, buf_ptr, (unsigned int) data);
  138.       return result;
  139.     } else {
  140.       /* No system Layer junk, just pretent we didn't peek,
  141.          and hereafter just call pure_get_more_data */
  142.       sys_layer = 0;
  143.       **bs_ptr = data;
  144.       *length_ptr = 1;
  145.       result = pure_get_more_data(*bs_ptr, *max_length, 
  146.                  length_ptr, buf_ptr, swap);
  147.       *buf_ptr = *bs_ptr;
  148.       return result;
  149.     }
  150.   }
  151.  
  152.   /* A system layer stream (called after the 1st time), call the specialist */
  153.   result = read_sys(bs_ptr, max_length, length_ptr, buf_ptr, 0);
  154.   return result;
  155. }
  156.  
  157.  
  158. /*
  159.  *-------------------------------------------------------------
  160.  *
  161.  * clear_data_stream
  162.  *
  163.  * Empties out internal buffers
  164.  *
  165.  *-------------------------------------------------------------
  166.  */
  167. void 
  168.   clear_data_stream(bs_ptr, max_length, length_ptr, buf_ptr)
  169. unsigned int **bs_ptr;
  170. int *max_length, *length_ptr;
  171. unsigned int **buf_ptr;
  172. {
  173.   /* Only internal buffer is in ReadPacket */
  174.   if (sys_layer) {
  175.     ReadPacket(KILL_BUFFER, bs_ptr, max_length, length_ptr, buf_ptr);
  176.   }
  177. }
  178.  
  179. /*
  180.  *-------------------------------------------------------------
  181.  *
  182.  * SeekStream
  183.  *
  184.  * Goto an offset in the steam
  185.  *
  186.  *-------------------------------------------------------------
  187.  */
  188. void
  189.   SeekStream(vid_stream)
  190. VidStream *vid_stream;
  191. {
  192.   int errno;
  193.   int code;
  194.   
  195.   if (seekValue < 0) return;
  196. #ifdef SEEK_SET
  197.   errno = fseek(input, seekValue, SEEK_SET);
  198. #else
  199.   errno = fseek(input, seekValue, 0);
  200. #endif
  201.   if (errno != 0) {
  202.     fprintf(stderr,"Error in seek (%d)\n",errno);
  203.     perror("mpeg_play");
  204.   }
  205.   seekValue = 0-seekValue;
  206.   totNumFrames = 0;
  207.  
  208.   /* clear that buffer */
  209.   bitBuffer = vid_stream->buffer = vid_stream->buf_start;
  210.   bufLength = vid_stream->buf_length = 0;
  211.   bitOffset = vid_stream->bit_offset = 0;
  212.  
  213.   /* Find a decent start code */
  214.  restart:
  215.  NO_ZEROS:
  216.   switch(fgetc(input)) {
  217.   case 0:    goto ONE_ZERO;
  218.   case EOF:  goto EOF_FOUND;
  219.   default:   goto NO_ZEROS;
  220.   }
  221.   
  222.  ONE_ZERO:
  223.   switch(fgetc(input)) {
  224.   case 0:    goto TWO_ZEROS;
  225.   case EOF:  goto EOF_FOUND;
  226.   default:   goto NO_ZEROS;
  227.   }
  228.   
  229.  TWO_ZEROS:
  230.   switch(fgetc(input)) {
  231.   case 0x01:  goto CODE_FOUND;
  232.   case 0x00:  goto TWO_ZEROS;
  233.   case EOF:   goto EOF_FOUND;
  234.   default:    goto NO_ZEROS;
  235.   }
  236.   
  237.  CODE_FOUND:
  238.   code = 0x00000100+fgetc(input);
  239.   if (sys_layer) {
  240.     clear_data_stream(&vid_stream->buf_start,
  241.               &vid_stream->max_buf_length,
  242.               &vid_stream->buf_length, 
  243.               &vid_stream->buffer);
  244.     if (((code & PACKET_START_CODE_MASK) == PACKET_START_CODE_PREFIX) &&
  245.     ((code & 0xff) >= 0xbc)) {
  246.       read_sys(&vid_stream->buf_start,
  247.            &vid_stream->max_buf_length,
  248.            &vid_stream->buf_length, 
  249.            &vid_stream->buffer,
  250.            code);
  251.       bufLength = vid_stream->buf_length;
  252.       while (TRUE) {
  253.     next_start_code();
  254.     show_bits32(code);
  255.     if ((code == SEQ_START_CODE) ||
  256.         (code == GOP_START_CODE)) return;
  257.     flush_bits32; 
  258.       }
  259.     }
  260.   } else {
  261.     if ((code == SEQ_START_CODE) ||
  262.     (code == GOP_START_CODE)) {
  263.       *vid_stream->buffer = code;
  264.       bufLength = vid_stream->buf_length = 1;
  265.       return;
  266.     }
  267.   }
  268.   goto restart;
  269.  
  270.  EOF_FOUND:   /* received EOF */
  271.   fprintf(stderr, "Hit EOF after seeking (offset %ld)\n",ftell(input));
  272.   exit(1);
  273.  
  274. }
  275.  
  276.  
  277. /*
  278.  *--------------------------------------------------------------
  279.  *
  280.  * pure_get_more_data --
  281.  *      (get_more_data from ver 2.0 with swap added)
  282.  *
  283.  *    Called by get_more_data to read in more data from
  284.  *      video MPG files (non-system-layer)
  285.  *
  286.  * Results:
  287.  *    Input buffer updated, buffer length updated.
  288.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  289.  *
  290.  * Side effects:
  291.  *      None.
  292.  *
  293.  *--------------------------------------------------------------
  294.  */
  295.  
  296. int 
  297. pure_get_more_data(buf_start, max_length, length_ptr, buf_ptr, swap)
  298.      unsigned int *buf_start;
  299.      int max_length;
  300.      int *length_ptr;
  301.      unsigned int **buf_ptr;
  302.      BOOLEAN swap;
  303. {
  304.   
  305.   int length, num_read, i;
  306.   unsigned int request;
  307.   unsigned char *buffer, *mark;
  308.   unsigned int *lmark;
  309.   
  310.   if (EOF_flag) return 0;
  311.   
  312.   length = *length_ptr;
  313.   buffer = (unsigned char *) *buf_ptr;
  314.   
  315.   if (length > 0) {
  316.     memcpy((unsigned char *) buf_start, buffer, (unsigned int) (length*4));
  317.     mark = ((unsigned char *) (buf_start + length));
  318.   }
  319.   else {
  320.     mark = (unsigned char *) buf_start;
  321.     length = 0;
  322.   }
  323.   
  324.   request = (max_length-length)*4;
  325.   
  326.   
  327.   num_read = fread(mark, 1, request, input);
  328.   
  329.   /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
  330.   {
  331.     int num_read_rounded;
  332.     unsigned char *index;
  333.     
  334.     num_read_rounded = 4*(num_read/4);
  335.     
  336.     /* this can happen only if num_read<request; i.e. end of file reached */
  337.     if ( num_read_rounded < num_read ) { 
  338.        num_read_rounded = 4*( num_read/4+1 );
  339.  
  340.          /* fill in with zeros */
  341.        for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
  342.  
  343.        /* advance to the next 4-byte boundary */
  344.        num_read = num_read_rounded;
  345.     }
  346.   }
  347.   
  348.   if (num_read < 0) {
  349.     return -1;
  350.   } else if (num_read == 0) {
  351.     *buf_ptr = buf_start;
  352.     
  353.     /* Make 32 bits after end equal to 0 and 32
  354.      * bits after that equal to seq end code
  355.      * in order to prevent messy data from infinite
  356.      * recursion.
  357.      */
  358.     
  359.     *(buf_start + length) = 0x0;
  360.     *(buf_start + length+1) = SEQ_END_CODE;
  361.     
  362.     EOF_flag = 1;
  363.     return 0;
  364.   }
  365.   
  366.   lmark = (unsigned int *) mark;
  367.   
  368.   num_read = num_read/4;
  369.   
  370.   if (swap) {
  371.     for (i = 0; i < num_read; i++) {
  372.       *lmark = htonl(*lmark);
  373.       lmark++;
  374.     }
  375.   }
  376.   
  377.   *buf_ptr = buf_start;
  378.   *length_ptr = length + num_read;
  379.   
  380.   return 1;
  381. }
  382.  
  383.  
  384.  
  385.  
  386. /* 
  387.   Here is the specialist.... 
  388.   Code is adapted from our program demux....
  389.   A bunch of this needs to be #ifdef ANALYSIS'ed
  390.   define __SYSREAD_LOGGING_ON__ to get  an output file for debugging
  391.   */
  392.  
  393.  
  394. /* Stream IDs */
  395. static int gAudioStreamID;
  396. static int gVideoStreamID;
  397. static int gReservedStreamID;
  398.  
  399. #ifdef ANALYSIS
  400. /* Statistics */
  401. static int gNumAudioPackets;
  402. static int gNumVideoPackets;
  403. static int gNumPaddingPackets;
  404. static int gNumReservedPackets;
  405. static int gNumPrivate_1_Packets;
  406. static int gNumPrivate_2_Packets;
  407. #endif
  408.  
  409. /*
  410.  *----------------------------------------------------------
  411.  *
  412.  *  read_sys
  413.  *
  414.  *      Parse out a packet of the system layer MPEG file.
  415.  *
  416.  *  Results:  Returns 0 if error or EOF
  417.  *            Returns 1 if more data read (could be just one int)
  418.  *
  419.  *  Side Effects:  ReadPacket can change *bs_ptr to be a new buffer
  420.  *                 buf_ptr will remain pointing at *length_ptr (at input)
  421.  *                         into the buffer
  422.  *                 *length_ptr will be changed to the new size
  423.  *                 *max_length can be changed if a new buffer is alloc'd
  424.  *
  425.  *----------------------------------------------------------
  426.  */
  427. int read_sys(bs_ptr, max_length, length_ptr, buf_ptr, start)
  428.      unsigned int **bs_ptr;
  429.      int *max_length, *length_ptr;
  430.      unsigned int **buf_ptr, start;  
  431.      /* start is either a start code or 0 to indicate continued parsing */
  432. {
  433.   unsigned int startCode;
  434.   int errorCode, PacketReply;
  435.   unsigned char packetID;
  436.   double systemClockTime;
  437.   unsigned long muxRate;
  438.   /* Statistics */
  439.   static int numPacks = 0;
  440.   static int numPackets = 0;
  441.   static int numSystemHeaders = 0;
  442.   static BOOLEAN Parse_done=FALSE;
  443.   BOOLEAN match;
  444.   
  445.   if (!start) {
  446.     errorCode = ReadStartCode(&startCode);
  447.     if (EOF_flag) return 0;
  448.     if (errorCode != 0) {
  449.       fprintf(stderr, "Unable to read initial pack start code\n");
  450.       return 0;
  451.     }}
  452.   else {
  453.     errorCode = 0;
  454.     startCode = start;
  455.   }
  456.   
  457.   while (1) {
  458.     match=FALSE;
  459.     if (startCode == PACK_START_CODE) {
  460.       ++numPacks; 
  461.       match = TRUE;
  462.       errorCode = ReadPackHeader( &systemClockTime, &muxRate);
  463.       if (errorCode != 0) {
  464.         fprintf(stderr, "Error in reading pack header\n");
  465.         return 0;
  466.       }
  467.       errorCode = ReadStartCode( &startCode);
  468.       if (errorCode != 0) {
  469.         fprintf(stderr, "Error in reading start code\n");
  470.         return 0;
  471.       }
  472.     }
  473.     if (startCode == SYSTEM_HEADER_START_CODE) {
  474.       ++numSystemHeaders; 
  475.       match = TRUE;
  476.       errorCode = ReadSystemHeader();
  477.       if (errorCode != 0) {
  478.         fprintf(stderr, "Error in reading system header\n");
  479.         return 0;
  480.       }
  481.       errorCode = ReadStartCode( &startCode);
  482.       if (errorCode != 0) {
  483.         fprintf(stderr,"Error in reading start code after system header\n");
  484.         return 0;
  485.       }
  486.     }
  487.     packetID = startCode & 0xff;
  488.     while (((startCode & PACKET_START_CODE_MASK) == PACKET_START_CODE_PREFIX) &&
  489.        (packetID >= 0xbc)) {
  490.       ++numPackets; 
  491.       match = TRUE;
  492.       packetID = startCode & 0xff;
  493.       PacketReply = ReadPacket(packetID, bs_ptr, max_length, length_ptr, buf_ptr);
  494.       switch (PacketReply) {
  495.       case 2: 
  496.         return 1;
  497.       case 1: 
  498.         return 0;
  499.       default: /* do nothing */
  500.         break;
  501.       }
  502.       errorCode = ReadStartCode( &startCode);
  503.       if (errorCode != 0) {
  504.         fprintf(stderr,"Error in start code after packet\n");
  505.         return 0;
  506.       }
  507.       if (startCode == PACK_START_CODE || startCode == ISO_11172_END_CODE) {
  508.         break;
  509.       }
  510.     }
  511.     
  512.     if (startCode == ISO_11172_END_CODE) {
  513.       match = TRUE;
  514.       if (Parse_done) {
  515.     return 1;
  516.       }
  517. #ifdef ANALYSIS
  518.       fprintf(stderr, "Successful parse of MPEG system level\n");
  519.       fprintf(stderr, "%d system headers, %d packs, %d packets\n",
  520.           numSystemHeaders, numPacks, numPackets);
  521.       fprintf(stderr, "%d audio packets, %d video packets, %d padding packets\n",
  522.           gNumAudioPackets, gNumVideoPackets, gNumPaddingPackets);
  523.       fprintf(stderr, "%d reserved packets, %d/%d private type 1/2 packets\n",
  524.           gNumReservedPackets, gNumPrivate_1_Packets, gNumPrivate_2_Packets);
  525. #endif
  526.       ReadPacket(NOT_PACKET_ID, bs_ptr, max_length, length_ptr, buf_ptr);
  527.       Parse_done = TRUE;
  528.       return 1;
  529.     }
  530.     if (errorCode != 0)
  531.       return 1;
  532.     if (! match) {
  533.       fprintf(stderr,"\nNo match found for start code %08x in system layer, skipping\n",startCode);
  534.       startCode = find_start_code();
  535.       if (startCode == EOF) {
  536.         EOF_flag = 1;
  537.         return 0;
  538.       }
  539.     }
  540.   }
  541. }
  542.  
  543.  
  544. /*
  545.  *-----------------------------------------------------------
  546.  *
  547.  *  ReadStartCode
  548.  *
  549.  *      Parses a start code out of the stream
  550.  *
  551.  *  Results/Side Effects:  Sets *startCode to the code, returns
  552.  *     1 on error, 0 on success
  553.  *
  554.  *-----------------------------------------------------------
  555.  */
  556. int ReadStartCode(startCode)
  557.      unsigned int *startCode;
  558. {
  559.   int numRead;
  560.   
  561.   numRead = fread((unsigned char *)startCode, 1, 4, input);
  562.   *startCode = htonl(*startCode);
  563.   
  564.   if (numRead < 4) {
  565.     EOF_flag = 1;
  566.     return 1;
  567.   }
  568.  
  569.   if ((*startCode&0xfffffe00) != 0) {
  570.     fprintf(stderr,"Problem with system layer parse, skipping to start code\n");
  571.     *startCode = find_start_code();
  572.     if (*startCode == EOF) {
  573.       EOF_flag = TRUE;
  574.       return 0;
  575.     }
  576.   }
  577.  
  578.   sysBytes += 4;
  579.   return 0;
  580. }
  581.  
  582.  
  583. /*
  584.  *-----------------------------------------------------------
  585.  *
  586.  *  find_start_code
  587.  *
  588.  *      Parses a start code out of the stream by tossing bytes until it gets one
  589.  *
  590.  *  Results/Side Effects:  Parses bytes of the stream, returns code
  591.  *                         Returns EOF in case of end of file
  592.  *
  593.  *-----------------------------------------------------------
  594.  */
  595. int find_start_code()
  596. {
  597.  NO_ZEROS:
  598.   switch(fgetc(input)) {
  599.   case 0:    goto ONE_ZERO;
  600.   case EOF:  goto EOF_FOUND;
  601.   default:   goto NO_ZEROS;
  602.   }
  603.  
  604.  ONE_ZERO:
  605.   switch(fgetc(input)) {
  606.   case 0:    goto TWO_ZEROS;
  607.   case EOF:  goto EOF_FOUND;
  608.   default:   goto NO_ZEROS;
  609.   }
  610.  
  611.  TWO_ZEROS:
  612.   switch(fgetc(input)) {
  613.   case 0x01:  goto CODE_FOUND;
  614.   case 0x00:  goto TWO_ZEROS;
  615.   case EOF:  goto EOF_FOUND;
  616.   default:    goto NO_ZEROS;
  617.   }
  618.  
  619.  CODE_FOUND:
  620.   return 0x00000100+fgetc(input);
  621.  
  622.  EOF_FOUND:   /* received EOF */
  623.   return EOF;
  624. }
  625.  
  626.  
  627.  
  628.  
  629. /*
  630.  *-----------------------------------------------------------------
  631.  *
  632.  *  ReadPackHeader
  633.  *
  634.  *      Parses out the PACK header
  635.  *
  636.  *  Returns: 1 on error, 0 on success
  637.  *
  638.  *-------------------------------------------------------------------
  639.  */
  640. int ReadPackHeader(systemClockTime,muxRate)
  641.      double *systemClockTime;
  642.      unsigned long *muxRate;
  643. {
  644.   int numRead;
  645.   unsigned char inputBuffer[PACK_HEADER_SIZE];
  646.   unsigned long systemClockRef;
  647.   unsigned char systemClockRefHiBit;
  648.   int errorCode;
  649.   
  650.   numRead = fread(inputBuffer, 1, PACK_HEADER_SIZE, input);
  651.   if (numRead < PACK_HEADER_SIZE) {
  652.     EOF_flag = 1;
  653.     return 1;
  654.   }
  655.   sysBytes += numRead;
  656.   ReadTimeStamp(inputBuffer, &systemClockRefHiBit, &systemClockRef);
  657.   errorCode = MakeFloatClockTime(systemClockRefHiBit, systemClockRef, 
  658.                  systemClockTime);
  659.   ReadRate(&inputBuffer[5], muxRate);
  660.   *muxRate *= MUX_RATE_SCALE_FACTOR;
  661.   return 0;
  662. }
  663.  
  664.  
  665. /*
  666.  *------------------------------------------------------------------
  667.  *
  668.  *   ReadSystemHeader
  669.  *
  670.  *      Parse out the system header, setup out stream IDs for parsing packets
  671.  *
  672.  *   Results:  Returns 1 on error, 0 on success.
  673.  *             Sets gAudioStreamID and gVideoStreamID
  674.  *
  675.  *------------------------------------------------------------------
  676.  */
  677. int ReadSystemHeader()
  678.   unsigned char *inputBuffer = NULL;
  679.   int numRead;
  680.   int pos;
  681.   unsigned short headerSize;
  682.   unsigned char streamID;
  683.   
  684.   numRead = fread((char *)&headerSize, 1, 2, input); 
  685.   headerSize = ntohs(headerSize);
  686.   if (numRead != 2) {
  687.     EOF_flag = 1;
  688.     return 1;
  689.   }
  690.   inputBuffer = (unsigned char *) malloc((unsigned int) headerSize+1);
  691.   sysBytes += headerSize;
  692.   if (inputBuffer == NULL) {
  693.     return 1;
  694.   }
  695.   inputBuffer[headerSize]=0;
  696.   numRead = fread(inputBuffer, 1, headerSize, input); 
  697.   if (numRead < headerSize) {
  698.     EOF_flag = 1;
  699.     return 1;
  700.   }
  701.   
  702.   pos = 6;
  703.   while ((inputBuffer[pos] & 0x80) == 0x80) {
  704.     streamID = inputBuffer[pos];
  705.     switch (streamID) {
  706.     case STD_VIDEO_STREAM_ID: 
  707.       break;
  708.     case STD_AUDIO_STREAM_ID: 
  709.       break;
  710.     case RESERVED_STREAM_ID: 
  711.       break;
  712.     case PADDING_STREAM_ID: 
  713.       break;
  714.     case PRIVATE_STREAM_1_ID: 
  715.       break;
  716.     case PRIVATE_STREAM_2_ID: 
  717.       break;
  718.     default:
  719.       if (streamID < MIN_STREAM_ID_ID) {
  720.     return 1;
  721.       }
  722.       switch (streamID >> 4) {
  723.       case 0xc:
  724.       case 0xd:
  725.     gAudioStreamID = streamID;
  726.     break;
  727.       case 0xe:
  728.     if ((gVideoStreamID != 0) && (gVideoStreamID!=streamID)) {
  729.       break;
  730.     }
  731.     gVideoStreamID = streamID;
  732.     break;
  733.       case 0xf:
  734.     gReservedStreamID = streamID;
  735.     break;
  736.       }
  737.       break;
  738.     }
  739.     pos += 3;
  740.   }
  741.   if (inputBuffer != NULL)
  742.     free(inputBuffer);
  743.   return 0;
  744. }
  745.  
  746.  
  747. /*
  748.  *-----------------------------------------------------------------
  749.  *
  750.  *  ReadPacket
  751.  *
  752.  *      Reads a single packet out of the stream, and puts it in the
  753.  *      buffer if it is video.
  754.  *
  755.  *  Results:
  756.  *      Changes the value of *length_ptr to be the new length (plus old)
  757.  *      If the buffer is too small, can change *bs_ptr, *max_length, and 
  758.  *      buf_ptr to be correct for a newly allocated buffer.
  759.  *
  760.  *  State:  
  761.  *      The buffer is in ints, but the packets can be an arbitrary number
  762.  *      of bytes, so leftover bytes are kept in static vars and added in 
  763.  *      on the next call.
  764.  *
  765.  *-----------------------------------------------------------------
  766.  */   
  767. int ReadPacket(packetID, bs_ptr, max_length, length_ptr, buf_ptr) 
  768.      unsigned char packetID;
  769.      unsigned int **bs_ptr;
  770.      int *max_length;
  771.      int *length_ptr;
  772.      unsigned int **buf_ptr;
  773.      /* Returns:
  774.     0 - no error, but not video packet we want
  775.     1 - error
  776.     2 - got video packet into buffer
  777.     */
  778. {   
  779.   int ioBytes;
  780.   unsigned char nextByte;
  781.   unsigned short packetLength;
  782.   unsigned char *packetBuffer = NULL;
  783.   int pos;
  784.   int numStuffBytes = 0;
  785.   unsigned int packetDataLength;
  786.   int byte_length;
  787.   unsigned char scratch[9];
  788.   /* Leftovers from previous video packets */
  789.   static unsigned int num_left = 0, leftover_bytes = 0;
  790.   
  791.   if (packetID == NOT_PACKET_ID) {
  792.     /* Gross hack to handle unread bytes before end of stream */
  793.     if (num_left != 0) {
  794.       /* Sigh, deal with previous leftovers */
  795.       *(*buf_ptr+*length_ptr) = leftover_bytes;
  796.       *(*buf_ptr+*length_ptr+1) = ISO_11172_END_CODE;
  797.       *length_ptr += 2;
  798.     } else {
  799.       *(*buf_ptr+*length_ptr) = ISO_11172_END_CODE;
  800.       *length_ptr += 1;
  801.     }
  802.     return 1;
  803.   } else if (packetID==KILL_BUFFER) {
  804.     num_left=0;
  805.     leftover_bytes=0;
  806.     return 0;
  807.   }
  808.   
  809.   ioBytes = fread(&packetLength, 1, 2, input);
  810.   packetLength = htons(packetLength);
  811.   if (ioBytes < 2) {
  812.     return 1;
  813.   }
  814.   if (packetID == gAudioStreamID) {
  815. #ifdef ANALYSIS
  816.     ++gNumAudioPackets;
  817. #endif
  818.   }
  819.   else if (packetID == gVideoStreamID) {
  820. #ifdef ANALYSIS     
  821.     ++gNumVideoPackets;
  822. #endif
  823.   }
  824.   else {
  825.     switch (packetID) {
  826.     case PADDING_STREAM_ID:
  827. #ifdef ANALYSIS
  828.       ++gNumPaddingPackets;
  829. #endif
  830.       break;
  831.     case RESERVED_STREAM_ID:
  832. #ifdef ANALYSIS
  833.       ++gNumReservedPackets;
  834. #endif
  835.       break;
  836.     case PRIVATE_STREAM_1_ID:
  837. #ifdef ANALYSIS
  838.       ++gNumPrivate_1_Packets;
  839. #endif
  840.       break;
  841.     case PRIVATE_STREAM_2_ID:
  842. #ifdef ANALYSIS
  843.       ++gNumPrivate_2_Packets;
  844. #endif
  845.       break;
  846.     default:
  847.       fprintf(stderr, "\nUnknown packet type encountered. P'bly audio? (%x) at %d\n",
  848.           packetID,(int) ftell(input));
  849.     }
  850.     fseek(input, packetLength, 1);
  851.     sysBytes += packetLength;
  852.     return 0;
  853.   }
  854.   fread(&nextByte,1,1,input);
  855.   pos = 0;
  856.   while (nextByte & 0x80) {
  857.     ++numStuffBytes;
  858.     ++pos;
  859.     fread(&nextByte,1,1,input);
  860.   }
  861.   if ((nextByte >> 6) == 0x01) {
  862.     pos += 2;
  863.     fread(&nextByte,1,1,input);
  864.     fread(&nextByte,1,1,input);
  865.   } 
  866.   if ((nextByte >> 4) == 0x02) {
  867.     fread(scratch,1,4,input);
  868.     fread(&nextByte,1,1,input);
  869.     pos += 5;
  870.   }
  871.   else if ((nextByte >> 4) == 0x03) {
  872.     fread(scratch,1,9,input);
  873.     fread(&nextByte,1,1,input);
  874.     pos += 10;
  875.   } 
  876.   else {
  877.     fread(&nextByte,1,1,input);
  878.     pos += 1;
  879.   }
  880.   /* Read all the headers, now make room for packet */
  881.   if (*bs_ptr + *max_length < *buf_ptr+ packetLength/4 + *length_ptr) {
  882.     if (*max_length - *length_ptr < packetLength/4) {
  883.       /* Buffer too small for a packet (plus whats there), 
  884.        * time to enlarge it! 
  885.        */
  886.       unsigned int *old = *bs_ptr;
  887.       *max_length = *length_ptr + packetLength/2;
  888.       *bs_ptr=(unsigned int *)malloc(*max_length*4);
  889.       if (*bs_ptr == NULL) {
  890.         return 1;
  891.       }
  892.       memcpy((unsigned char *)*bs_ptr, *buf_ptr, (unsigned int) *length_ptr*4);
  893.       free(old);
  894.       *buf_ptr = *bs_ptr;
  895.     } else {
  896.       memcpy((unsigned char *)*bs_ptr, *buf_ptr, (unsigned int) *length_ptr*4);
  897.       *buf_ptr = *bs_ptr;
  898.     }}
  899.   byte_length = *length_ptr*4;
  900.   if (num_left != 0) {
  901.     /* Sigh, deal with previous leftovers */
  902.     byte_length += num_left;
  903.     *(*buf_ptr+*length_ptr) = leftover_bytes;
  904.   }
  905.   packetBuffer=((unsigned char *)*buf_ptr)+byte_length;
  906.   packetDataLength = packetLength - pos;
  907.   *packetBuffer++ = nextByte;
  908.   if (packetID == gVideoStreamID) {
  909.     ioBytes = fread(packetBuffer, 1, packetDataLength-1, input);
  910.     if (ioBytes != packetDataLength-1) {
  911.       EOF_flag = 1;
  912.       return 1;
  913.     }
  914.     if (1 != ntohl(1)) {
  915.       unsigned int *mark = *buf_ptr+*length_ptr;
  916.       int i;
  917.       
  918.       for (i=0; i < ((packetDataLength+num_left)&0xfffffffc); i+=4) {
  919.         *mark=ntohl(*mark);
  920.         mark++;
  921.       }
  922.     }
  923.     byte_length = byte_length + packetDataLength;
  924.     num_left = byte_length % 4;
  925.     *length_ptr = byte_length / 4;
  926.     leftover_bytes = *(*buf_ptr + *length_ptr);
  927.     sysBytes += packetLength - packetDataLength;
  928.     vidBytes += packetDataLength;
  929.     return 2;
  930.   }
  931.   else if (packetID == gAudioStreamID) { 
  932.     sysBytes += packetLength - packetDataLength;
  933.     audBytes += packetDataLength;
  934.     packetBuffer = (unsigned char *)(*buf_ptr + *length_ptr + 1);
  935.     fread(packetBuffer, 1, packetDataLength - 1, input);
  936.   }
  937.   else /* Donno what it is, just nuke it */ {
  938.     /* This code should be unreachable */
  939.     sysBytes += packetLength;
  940.     packetBuffer = (unsigned char *)(*buf_ptr + *length_ptr + 1);
  941.     fread(packetBuffer, 1, packetDataLength - 1, input);
  942.   }
  943.   return 0; 
  944. }
  945.  
  946.  
  947. /*
  948.  * The remaining procedures are formatting utility procedures.
  949.  */
  950. void ReadTimeStamp(inputBuffer,hiBit,low4Bytes)
  951.      unsigned char *inputBuffer, *hiBit;
  952.      unsigned long *low4Bytes;
  953. {
  954.   *hiBit = ((unsigned long)inputBuffer[0] >> 3) & 0x01;
  955.   *low4Bytes = (((unsigned long)inputBuffer[0] >> 1) & 0x03) << 30; 
  956.   *low4Bytes |= (unsigned long)inputBuffer[1] << 22; 
  957.   *low4Bytes |= ((unsigned long)inputBuffer[2] >> 1) << 15; 
  958.   *low4Bytes |= (unsigned long)inputBuffer[3] << 7; 
  959.   *low4Bytes |= ((unsigned long)inputBuffer[4]) >> 1; 
  960. }
  961.  
  962. void ReadSTD(inputBuffer,stdBufferScale,stdBufferSize) 
  963. unsigned char *inputBuffer;
  964. unsigned char *stdBufferScale;
  965. unsigned long *stdBufferSize;
  966. {
  967.   *stdBufferScale = ((inputBuffer[0] & 0x20) >> 5); 
  968.   *stdBufferSize = ((unsigned long)inputBuffer[0] & 0x1f) << 8;
  969.   *stdBufferSize |= (unsigned long)inputBuffer[1];
  970. }
  971.  
  972.  
  973. void ReadRate(inputBuffer,rate)
  974.      unsigned char *inputBuffer;
  975.      unsigned long *rate;
  976. {
  977.   *rate = (inputBuffer[0] & 0x7f) << 15;
  978.   *rate |= inputBuffer[1] << 7;
  979.   *rate |= (inputBuffer[2] & 0xfe) >> 1;
  980. }
  981.  
  982. #define FLOAT_0x10000 (double)((unsigned long)1 << 16)
  983.  
  984. int MakeFloatClockTime(hiBit,low4Bytes,floatClockTime)
  985.      unsigned char hiBit;
  986.      unsigned long low4Bytes;
  987.      double *floatClockTime;
  988. {
  989.   if (hiBit != 0 && hiBit != 1) {
  990.     *floatClockTime = 0.0;
  991.     return 1;
  992.   }
  993.   *floatClockTime 
  994.     = (double)hiBit*FLOAT_0x10000*FLOAT_0x10000 + (double)low4Bytes;
  995.   *floatClockTime /= (double)STD_SYSTEM_CLOCK_FREQ;
  996.   return 0;
  997. }
  998.